css: Implement font-variant-numeric
authorMatthias Clasen <mclasen@redhat.com>
Mon, 18 Sep 2017 11:34:46 +0000 (07:34 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Mon, 18 Sep 2017 18:26:57 +0000 (14:26 -0400)
This gets translated to the corresponding OpenType features.

gtk/gtkcssstyle.c
gtk/gtkcssstylepropertyimpl.c
gtk/gtkcsstypesprivate.h

index 8b35f0e5ceac2a74ab4404b1dd3f30ed51c2063e..33960349d8cb042bacbfc19c661c2a7cc16979e9 100644 (file)
@@ -229,6 +229,7 @@ gtk_css_style_get_pango_attributes (GtkCssStyle *style)
   GtkCssValue *ligatures;
   GtkCssValue *position;
   GtkCssValue *caps;
+  GtkCssValue *numeric;
   GString *s;
   int i;
 
@@ -345,6 +346,29 @@ gtk_css_style_get_pango_attributes (GtkCssStyle *style)
       g_string_append (s, "titl 1");
     }
 
+  numeric = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_VARIANT_NUMERIC);
+  for (i = 0; i < _gtk_css_array_value_get_n_values (numeric); i++)
+    {
+      GtkCssValue *value = _gtk_css_array_value_get_nth (numeric, i);
+      if (s->len > 0) g_string_append (s, ", ");
+      if (strcmp (_gtk_css_ident_value_get (value), "lining-nums") == 0)
+        g_string_append (s, "lnum 1");
+      else if (strcmp (_gtk_css_ident_value_get (value), "oldstyle-nums") == 0)
+        g_string_append (s, "onum 1");
+      else if (strcmp (_gtk_css_ident_value_get (value), "proportional-nums") == 0)
+        g_string_append (s, "pnum 1");
+      else if (strcmp (_gtk_css_ident_value_get (value), "tabular-nums") == 0)
+        g_string_append (s, "tnum 1");
+      else if (strcmp (_gtk_css_ident_value_get (value), "diagonal-fractions") == 0)
+        g_string_append (s, "frac 1");
+      else if (strcmp (_gtk_css_ident_value_get (value), "stacked-fractions") == 0)
+        g_string_append (s, "afrc 1");
+      else if (strcmp (_gtk_css_ident_value_get (value), "ordinal") == 0)
+        g_string_append (s, "ordn 1");
+      else if (strcmp (_gtk_css_ident_value_get (value), "slashed-zero") == 0)
+        g_string_append (s, "zero 1");
+    }
+
   attrs = add_pango_attr (attrs, pango_attr_font_features_new (s->str));
   g_string_free (s, TRUE);
 
index 12b4f3ce158affbcd21b17cd4fe88edcf89ecfbc..a0311b37b0b2bea4d2e22907bf798bac0a317525 100644 (file)
@@ -657,6 +657,85 @@ parse_font_variant_caps (GtkCssStyleProperty *property,
   return value;
 }
 
+static GtkCssValue *
+parse_font_variant_numeric (GtkCssStyleProperty *property,
+                            GtkCssParser        *parser)
+{
+  GtkCssValue *value = NULL;
+
+  if (_gtk_css_parser_try (parser, "normal", TRUE))
+    value = _gtk_css_array_value_new (_gtk_css_ident_value_new ("normal"));
+  else
+    {
+      GtkCssValue *values[5] = { NULL, NULL, NULL, NULL };
+      guint n_values = 0;
+      guint old_n;
+      gboolean figure = FALSE;
+      gboolean spacing = FALSE;
+      gboolean fraction = FALSE;
+      gboolean ordinal = FALSE;
+      gboolean zero = FALSE;
+
+      do {
+        old_n = n_values;
+        if (!figure)
+          {
+            values[n_values] = _gtk_css_ident_value_try (parser, "lining-nums", "oldstyle-nums", NULL);
+            if (values[n_values])
+              {
+                n_values++;
+                figure = TRUE;
+              }
+         }
+        if (!spacing)
+          {
+            values[n_values] = _gtk_css_ident_value_try (parser, "proportional-nums", "tabular-nums", NULL);
+            if (values[n_values])
+              {
+                n_values++;
+                spacing = TRUE;
+              }
+         }
+        if (!fraction)
+          {
+            values[n_values] = _gtk_css_ident_value_try (parser, "diagonal-fractions", "stacked-fractions", NULL);
+            if (values[n_values])
+              {
+                n_values++;
+                fraction = TRUE;
+              }
+         }
+        if (!ordinal)
+          {
+            values[n_values] = _gtk_css_ident_value_try (parser, "ordinal", NULL);
+            if (values[n_values])
+              {
+                n_values++;
+                ordinal = TRUE;
+              }
+         }
+        if (!zero)
+          {
+            values[n_values] = _gtk_css_ident_value_try (parser, "slashed-zero", NULL);
+            if (values[n_values])
+              {
+                n_values++;
+                zero = TRUE;
+              }
+         }
+        if (old_n == n_values)
+          {
+            _gtk_css_parser_error (parser, "Not a valid value");
+            return NULL;
+          }
+      } while (!value_is_done_parsing (parser));
+
+      value = _gtk_css_array_value_new_from_array (values, n_values);
+    }
+
+  return value;
+}
+
 static GtkCssValue *
 box_shadow_value_parse (GtkCssStyleProperty *property,
                         GtkCssParser        *parser)
@@ -1174,6 +1253,14 @@ _gtk_css_style_property_init_properties (void)
                                           parse_font_variant_caps,
                                           NULL,
                                           _gtk_css_ident_value_new ("normal"));
+  gtk_css_style_property_register        ("font-variant-numeric",
+                                          GTK_CSS_PROPERTY_FONT_VARIANT_NUMERIC,
+                                          G_TYPE_NONE,
+                                          0,
+                                          GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_TEXT_ATTRS,
+                                          parse_font_variant_numeric,
+                                          NULL,
+                                          _gtk_css_array_value_new (_gtk_css_ident_value_new ("normal")));
   gtk_css_style_property_register        ("text-shadow",
                                           GTK_CSS_PROPERTY_TEXT_SHADOW,
                                           G_TYPE_NONE,
index 3adb14ca00f958ff64d65ec8401df2fe282fcccb..5ca7b7aa3af68d11df19a24ec0b61565ddae3d30 100644 (file)
@@ -167,6 +167,7 @@ enum { /*< skip >*/
   GTK_CSS_PROPERTY_FONT_VARIANT_LIGATURES,
   GTK_CSS_PROPERTY_FONT_VARIANT_POSITION,
   GTK_CSS_PROPERTY_FONT_VARIANT_CAPS,
+  GTK_CSS_PROPERTY_FONT_VARIANT_NUMERIC,
   GTK_CSS_PROPERTY_TEXT_SHADOW,
   GTK_CSS_PROPERTY_BOX_SHADOW,
   GTK_CSS_PROPERTY_MARGIN_TOP,